package com.zxy.ziems.server.file.util;

import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.math.BigDecimal;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @author chdzq
 * @create 2023/3/21
 */
public class FileSupport {
    private static Logger logger = LoggerFactory.getLogger(File.class);
    public static Supplier<String> generateRandomFileName = () -> {
        return UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
    };
    public static Function<String, Boolean> deleteFile = (path) -> {
        Boolean flag = Boolean.FALSE;

        try {
            File file = new File(path);
            if (file.exists() && file.isFile()) {
                flag = file.delete();
            }
        } catch (Exception var3) {
            logger.error("Delete File ->{} fail : Cause ->{}, Message ->{}", new Object[]{path, var3.getCause(), var3.getMessage()});
        }

        return flag;
    };
    public static BiFunction<String, String, Boolean> remove = (original, recent) -> {
        Boolean flag = Boolean.TRUE;

        try {
            File file = new File(recent);
            if (!file.getParentFile().exists()) {
                file.mkdirs();
            }

            flag = (new File(original)).renameTo(file);
        } catch (Exception var4) {
            flag = Boolean.FALSE;
            logger.error("Remove File -> {} To -> {} fail: Cause->{}  ,Message ->{}", new Object[]{original, recent, var4.getCause(), var4.getMessage()});
        }

        return flag;
    };
    public static BiConsumer<String, HttpServletResponse> download = (path, response) -> {
        InputStream is = null;

        try {
            File file = new File(path);
            is = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int i;
            while((i = is.read(buffer)) > 0) {
                response.getOutputStream().write(buffer, 0, i);
            }
        } catch (Exception var14) {
            logger.error("download file path->{}  Failed: Cause->{}  ,Message ->{}", var14.getCause(), var14.getMessage());
        } finally {
            try {
                is.close();
            } catch (IOException var13) {
                logger.error("Close IO Stream Fail : Cause ->{}, Message ->{}", var13.getCause(), var13.getMessage());
            }

        }

    };

    public FileSupport() {
    }

    public static Boolean write(String path, InputStream is) throws Exception {
        Boolean flag = Boolean.TRUE;
        OutputStream os = null;

        try {
            File file = new File(path);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }

            os = new FileOutputStream(file);
            byte[] buf = new byte[1024];

            int len;
            while(-1 != (len = is.read(buf))) {
                os.write(buf, 0, len);
            }
        } finally {
            try {
                os.flush();
                os.close();
                is.close();
            } catch (IOException var12) {
                flag = Boolean.FALSE;
                logger.error("Close IO Stream Fail : Cause ->{}, Message ->{}", var12.getCause(), var12.getMessage());
            }

        }

        return flag;
    }

    public static Boolean copy(String original, String recent) throws Exception {
        Boolean flag = Boolean.TRUE;
        InputStream is = null;
        OutputStream os = null;

        try {
            File tmp = new File(original);
            is = new FileInputStream(tmp);
            File file = new File(recent);
            if (!file.exists()) {
                file.getParentFile().mkdirs();
            }

            os = new FileOutputStream(file);
            byte[] buf = new byte[1024];

            int len;
            while(-1 != (len = is.read(buf))) {
                os.write(buf, 0, len);
            }
        } finally {
            try {
                os.flush();
                os.close();
                is.close();
            } catch (IOException var14) {
                flag = Boolean.FALSE;
                logger.error("Close IO Stream Fail : Cause ->{}, Message ->{}", var14.getCause(), var14.getMessage());
            }

        }

        return flag;
    }

    public static Boolean deleteDirectory(String dir) {
        Boolean flag = Boolean.FALSE;

        try {
            if (!dir.endsWith(File.separator)) {
                dir = dir + File.separator;
            }

            File file = new File(dir);
            if (file.exists() && file.isDirectory()) {
                File[] filies = file.listFiles();
                if (filies != null && filies.length > 0) {
                    Arrays.stream(filies).forEach((f) -> {
                        if (f.isFile()) {
                            deleteFile.apply(f.getAbsolutePath());
                        } else if (f.isDirectory()) {
                            deleteDirectory(f.getAbsolutePath());
                        }

                    });
                }

                flag = file.delete();
            }
        } catch (Exception var4) {
            logger.error("Delete Dir ->{} Fail : Cause ->{}, Message ->{}", new Object[]{dir, var4.getCause(), var4.getMessage()});
        }

        return flag;
    }

    public static BigDecimal process(String path) throws Exception {
        File tmp = new File((String)FileUtil.getTmpFilePath.apply(path));
        if (!tmp.exists()) {
            return (new BigDecimal(100)).setScale(2, 4);
        } else {
            byte[] complete;
            try {
                complete = FileUtils.readFileToByteArray(tmp);
            } catch (FileNotFoundException var5) {
                return (new BigDecimal(100)).setScale(2, 4);
            }

            int count = 0;

            for(int i = 0; i < complete.length; ++i) {
                if (complete[i] == 127) {
                    ++count;
                }
            }

            return (new BigDecimal(count)).divide(new BigDecimal(complete.length), 2, 4);
        }
    }
}

